package com.I9lou.se.lurker.facet.search.support;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.lucene.search.IndexSearcher;

import com.I9lou.se.lurker.facet.search.MultiFacetService;
import com.I9lou.se.lurker.remote.SearchCommand;

/**
 * 用FieldCache实现统计，由于FieldCache是返回全部搜索结果，所以排序跟分页要手工实现
 * 
 * @author moshan
 * 
 */
public class SimpleMultiFacetService implements MultiFacetService {

	@Override
	public List<Map<String, Object>> search(IndexSearcher searcher, SearchCommand command, String facetField) {
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		MultiFacetCollector facetCollector = new MultiFacetCollector(facetField);
		try {
			searcher.search(command.getQuery(), facetCollector);
		} catch (IOException e) {
			throw new IllegalStateException(e);
		}
		Map<String, Integer> map = facetCollector.facetMap;
		List<Map<String, Object>> categoriesList = new ArrayList<Map<String, Object>>();
		for (Map.Entry<String, Integer> entry : map.entrySet()) {
			Map<String, Object> resultMap = new HashMap<String, Object>();
			resultMap.put("count", entry.getValue());
			resultMap.put("categories", entry.getKey());
			categoriesList.add(resultMap);
		}
		categoriesList = sort(categoriesList);
		Map<String, Object> totalMap = new HashMap<String, Object>();
		totalMap.put("totalCount", facetCollector.totalCount);
		totalMap.put("pageCount", categoriesList.size());
		result.add(0, totalMap);
		result.addAll(categoriesList);

		return result;
	}

	/**
	 * 按照count值从大到小排序
	 * 
	 * @param list
	 * @return
	 */
	private List<Map<String, Object>> sort(List<Map<String, Object>> list) {
		Collections.sort(list, new Comparator<Map<String, Object>>() {

			@Override
			public int compare(Map<String, Object> o1, Map<String, Object> o2) {
				if ((Integer) o1.get("count") > (Integer) o2.get("count")) {
					return -1;
				} else if ((Integer) o1.get("count") < (Integer) o2.get("count")) {
					return 1;
				} else {
					return 0;
				}
			}

		});

		return list;
	}

}
